package cn.edu.fudan.tools;

import cn.edu.fudan.data.*;
import cn.edu.fudan.type.*;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class PAMAPClassifier {
	private static Logger logger = Logger.getLogger(PAMAPClassifier.class);
	private static PAMAPDimension dimension = PAMAPDimension.z_ankle;

	public void OneSideClassifier(String subject) {
		Config config;
		try {
			config = new GetConfig().getConfig();
			logger.info(config);

			String path = config.getPath();

			String filePath = path + subject + "_extract";
			String trainPath = path + subject + "\\train.txt";
			String testPath = path + subject + "\\test.txt";

			ReadData readData = new ReadData();
			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature = new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();

			List<DataItem> data = new ArrayList<DataItem>();
			List<List<Long>> timepoints = new ArrayList<>();
			List<List<Long>> testpoints = new ArrayList<>();
			try {
				data = readData.readPAMAPDataFromFile(filePath, true, dimension);
				timepoints = readData.readTimePoint(trainPath, true);

				testpoints = readData.readTimePoint(testPath, true);
			} catch (Exception e) {
				// TODO Auto-generated catch block e.printStackTrace();
			}
			if (data.size() > 0) {
				long begin = System.currentTimeMillis();
				Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(),
						config.getInterval());

				// two-class
				List<List<DataItem>> data_A = slideWindow.extractWindow(feature.getAbnormal(), timepoints.get(0),
						config.getWindow_length());
				List<List<DataItem>> data_B = slideWindow.extractWindow(feature.getAbnormal(), timepoints.get(1),
						config.getWindow_length());

				List<List<DataItem>> test_A = slideWindow.extractWindow(feature.getAbnormal(), testpoints.get(0),
						config.getWindow_length());
				List<List<DataItem>> test_B = slideWindow.extractWindow(feature.getAbnormal(), testpoints.get(1),
						config.getWindow_length());

				List<List<Double>> maps_A = new ArrayList<>();
				List<List<Double>> maps_B = new ArrayList<>();

				List<List<Double>> testmaps_A = new ArrayList<>();
				List<List<Double>> testmaps_B = new ArrayList<>();

				for (int i = 0; i < data_A.size(); i++) {
					List<Double> map = handelFeature.handleFeature(data_A.get(i), config.getN_segment());
					maps_A.add(map);
				}

				for (int i = 0; i < data_B.size(); i++) {
					List<Double> map = handelFeature.handleFeature(data_B.get(i), config.getN_segment());
					maps_B.add(map);
				}

				for (int i = 0; i < test_A.size(); i++) {
					List<Double> map = handelFeature.handleFeature(test_A.get(i), config.getN_segment());
					testmaps_A.add(map);
				}

				for (int i = 0; i < test_B.size(); i++) {
					List<Double> map = handelFeature.handleFeature(test_B.get(i), config.getN_segment());
					testmaps_B.add(map);
				}

				logger.info("Training Phase(Class A)");
				handleDistance.calAccuracy(maps_A, maps_B, maps_A, config.getK());

				logger.info("Training Phase(Class B)");
				handleDistance.calAccuracy(maps_B, maps_A, maps_B, config.getK());

				logger.info("Class A: ");
				handleDistance.calAccuracy(maps_A, maps_B, testmaps_A, config.getK());

				logger.info("Class B: ");
				handleDistance.calAccuracy(maps_B, maps_A, testmaps_B, config.getK());
				long end = System.currentTimeMillis();
				logger.info("Run for " + (end - begin) / (double) 1000 + "seconds.");

				 List<DataItem> data_full =
				 readData.readPAMAPDataFromFile(filePath, dimension);
				 printOneSidePattern(data_full, data_A, data_B, path +  //
				 subject, config.getWindow_length(), 0);
				 printOneSidePattern(data_full, test_A, test_B, path +
				 subject, config.getWindow_length(), 1);
				
//				FileWriter fWriter = null;
//							
//				for(int i = 0; i < data_A.size(); i ++){
//					fWriter = new FileWriter(path + subject + "\\abnormal\\posi\\"+(i+1));
//					for(DataItem dItem : data_A.get(i)){
//						fWriter.write(dItem.getTimestamp()+"\t"+dItem.getValue()+"\r\n");
//					}
//					fWriter.close();
//				}
//				
//				for(int i = 0; i < data_B.size(); i ++){
//					fWriter = new FileWriter(path + subject + "\\abnormal\\nega\\"+(i+1));
//					for(DataItem dItem : data_B.get(i)){
//						fWriter.write(dItem.getTimestamp()+"\t"+dItem.getValue()+"\r\n");
//					}
//					fWriter.close();
//				}
//				
//				for (int i = 0; i < maps_A.size(); i ++) {
//					fWriter = new FileWriter(path + subject + "\\abnormal\\map_posi\\"+(i+1));
//					for(Double item : maps_A.get(i)){
//						fWriter.write(item+"\t");
//					}
//					fWriter.close();
//				}
//				
//				for (int i = 0; i < maps_B.size(); i ++) {
//					fWriter = new FileWriter(path + subject + "\\abnormal\\map_nega\\"+(i+1));
//					for(Double item : maps_B.get(i)){
//						fWriter.write(item+"\t");
//					}
//					fWriter.close();
//				}
			}

		} catch (IOException e1) { // TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}


	public void OneSidePaaClassifier(String subject) {
		Config config;
		try {
			config = new GetConfig().getConfig();
			logger.info(config);

			String path = config.getPath();

			String filePath = path + subject + "_extract";
			String trainPath = path + subject + "\\train.txt";
			String testPath = path + subject + "\\test.txt";

			ReadData readData = new ReadData();
			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature = new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();


			List<DataItem> data = new ArrayList<DataItem>();
			List<List<Long>> timepoints = new ArrayList<>();
			List<List<Long>> testpoints = new ArrayList<>();
			try {
				data = readData.readPAMAPDataFromFile(filePath, true, dimension);
				timepoints = readData.readTimePoint(trainPath, true);

				testpoints = readData.readTimePoint(testPath, true);
			} catch (Exception e) {
				// TODO Auto-generated catch block e.printStackTrace();
			}
			if (data.size() > 0) {
				long begin = System.currentTimeMillis();
				Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(),
						config.getInterval());

				// two-class
				List<List<DataItem>> data_A = slideWindow.extractWindow(feature.getAbnormal(), timepoints.get(0),
						config.getWindow_length());
				List<List<DataItem>> data_B = slideWindow.extractWindow(feature.getAbnormal(), timepoints.get(1),
						config.getWindow_length());

				List<List<DataItem>> test_A = slideWindow.extractWindow(feature.getAbnormal(), testpoints.get(0),
						config.getWindow_length());
				List<List<DataItem>> test_B = slideWindow.extractWindow(feature.getAbnormal(), testpoints.get(1),
						config.getWindow_length());

				List<List<Double>> maps_A = new ArrayList<>();
				List<List<Double>> maps_B = new ArrayList<>();

				List<List<Double>> testmaps_A = new ArrayList<>();
				List<List<Double>> testmaps_B = new ArrayList<>();

				for (int i = 0; i < data_A.size(); i++) {
					List<Double> map = handelFeature.handlePaaFeature(data_A.get(i), config.getN_segment());
					maps_A.add(map);
				}

				for (int i = 0; i < data_B.size(); i++) {
					List<Double> map = handelFeature.handlePaaFeature(data_B.get(i), config.getN_segment());
					maps_B.add(map);
				}

				for (int i = 0; i < test_A.size(); i++) {
					List<Double> map = handelFeature.handlePaaFeature(test_A.get(i), config.getN_segment());
					testmaps_A.add(map);
				}

				for (int i = 0; i < test_B.size(); i++) {
					List<Double> map = handelFeature.handlePaaFeature(test_B.get(i), config.getN_segment());
					testmaps_B.add(map);
				}

				logger.info("Training Phase(Class A)");
				handleDistance.calAccuracy(maps_A, maps_B, maps_A, config.getK());

				logger.info("Training Phase(Class B)");
				handleDistance.calAccuracy(maps_B, maps_A, maps_B, config.getK());

				logger.info("Class A: ");
				handleDistance.calAccuracy(maps_A, maps_B, testmaps_A, config.getK());

				logger.info("Class B: ");
				handleDistance.calAccuracy(maps_B, maps_A, testmaps_B, config.getK());
				long end = System.currentTimeMillis();
				logger.info("Run for " + (end - begin) / (double) 1000 + "seconds.");

				List<DataItem> data_full =
						readData.readPAMAPDataFromFile(filePath, dimension);
				printOneSidePattern(data_full, data_A, data_B, path +  //
						subject, config.getWindow_length(), 0);
				printOneSidePattern(data_full, test_A, test_B, path +
						subject, config.getWindow_length(), 1);

//				FileWriter fWriter = null;
//
//				for(int i = 0; i < data_A.size(); i ++){
//					fWriter = new FileWriter(path + subject + "\\abnormal\\posi\\"+(i+1));
//					for(DataItem dItem : data_A.get(i)){
//						fWriter.write(dItem.getTimestamp()+"\t"+dItem.getValue()+"\r\n");
//					}
//					fWriter.close();
//				}
//
//				for(int i = 0; i < data_B.size(); i ++){
//					fWriter = new FileWriter(path + subject + "\\abnormal\\nega\\"+(i+1));
//					for(DataItem dItem : data_B.get(i)){
//						fWriter.write(dItem.getTimestamp()+"\t"+dItem.getValue()+"\r\n");
//					}
//					fWriter.close();
//				}
//
//				for (int i = 0; i < maps_A.size(); i ++) {
//					fWriter = new FileWriter(path + subject + "\\abnormal\\map_posi\\"+(i+1));
//					for(Double item : maps_A.get(i)){
//						fWriter.write(item+"\t");
//					}
//					fWriter.close();
//				}
//
//				for (int i = 0; i < maps_B.size(); i ++) {
//					fWriter = new FileWriter(path + subject + "\\abnormal\\map_nega\\"+(i+1));
//					for(Double item : maps_B.get(i)){
//						fWriter.write(item+"\t");
//					}
//					fWriter.close();
//				}
			}

		} catch (IOException e1) { // TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	public void OneSideSrdClassifier(String subject,int N_segment) { //自己给段数的分段标准差做特征提取的KNN分类器
		Config config;
		try {
			config = new GetConfig().getConfig();
			logger.info(config);

			String path = config.getPath();

			String filePath = path + subject + "_extract";
			String trainPath = path + subject + "\\train.txt";
			String testPath = path + subject + "\\test.txt";

			ReadData readData = new ReadData();
			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature = new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();


			List<DataItem> data = new ArrayList<DataItem>();
			List<List<Long>> timepoints = new ArrayList<>();
			List<List<Long>> testpoints = new ArrayList<>();
			try {
				data = readData.readPAMAPDataFromFile(filePath, true, dimension);
				timepoints = readData.readTimePoint(trainPath, true);

				testpoints = readData.readTimePoint(testPath, true);
			} catch (Exception e) {
				// TODO Auto-generated catch block e.printStackTrace();
			}
			if (data.size() > 0) {
				long begin = System.currentTimeMillis();
				Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(),
						config.getInterval());

				// two-class
				List<List<DataItem>> data_A = slideWindow.extractWindow(feature.getAbnormal(), timepoints.get(0),
						config.getWindow_length());
				List<List<DataItem>> data_B = slideWindow.extractWindow(feature.getAbnormal(), timepoints.get(1),
						config.getWindow_length());

				List<List<DataItem>> test_A = slideWindow.extractWindow(feature.getAbnormal(), testpoints.get(0),
						config.getWindow_length());
				List<List<DataItem>> test_B = slideWindow.extractWindow(feature.getAbnormal(), testpoints.get(1),
						config.getWindow_length());

				List<List<Double>> maps_A = new ArrayList<>();
				List<List<Double>> maps_B = new ArrayList<>();

				List<List<Double>> testmaps_A = new ArrayList<>();
				List<List<Double>> testmaps_B = new ArrayList<>();

				for (int i = 0; i < data_A.size(); i++) {
					List<Double> map = handelFeature.handleSrdFeature(data_A.get(i), N_segment);
					maps_A.add(map);
				}

				for (int i = 0; i < data_B.size(); i++) {
					List<Double> map = handelFeature.handleSrdFeature(data_B.get(i), N_segment);
					maps_B.add(map);
				}

				for (int i = 0; i < test_A.size(); i++) {
					List<Double> map = handelFeature.handleSrdFeature(test_A.get(i), N_segment);
					testmaps_A.add(map);
				}

				for (int i = 0; i < test_B.size(); i++) {
					List<Double> map = handelFeature.handleSrdFeature(test_B.get(i), N_segment);
					testmaps_B.add(map);
				}

				logger.info("Training Phase(Class A)");
				handleDistance.calAccuracy(maps_A, maps_B, maps_A, config.getK());

				logger.info("Training Phase(Class B)");
				handleDistance.calAccuracy(maps_B, maps_A, maps_B, config.getK());

				logger.info("Class A: ");
				handleDistance.calAccuracy(maps_A, maps_B, testmaps_A, config.getK());

				logger.info("Class B: ");
				handleDistance.calAccuracy(maps_B, maps_A, testmaps_B, config.getK());
				long end = System.currentTimeMillis();
				logger.info("Run for " + (end - begin) / (double) 1000 + "seconds.");

				List<DataItem> data_full =
						readData.readPAMAPDataFromFile(filePath, dimension);
				printOneSidePattern(data_full, data_A, data_B, path +  //
						subject, config.getWindow_length(), 0);
				printOneSidePattern(data_full, test_A, test_B, path +
						subject, config.getWindow_length(), 1);

//				FileWriter fWriter = null;
//
//				for(int i = 0; i < data_A.size(); i ++){
//					fWriter = new FileWriter(path + subject + "\\abnormal\\posi\\"+(i+1));
//					for(DataItem dItem : data_A.get(i)){
//						fWriter.write(dItem.getTimestamp()+"\t"+dItem.getValue()+"\r\n");
//					}
//					fWriter.close();
//				}
//
//				for(int i = 0; i < data_B.size(); i ++){
//					fWriter = new FileWriter(path + subject + "\\abnormal\\nega\\"+(i+1));
//					for(DataItem dItem : data_B.get(i)){
//						fWriter.write(dItem.getTimestamp()+"\t"+dItem.getValue()+"\r\n");
//					}
//					fWriter.close();
//				}
//
//				for (int i = 0; i < maps_A.size(); i ++) {
//					fWriter = new FileWriter(path + subject + "\\abnormal\\map_posi\\"+(i+1));
//					for(Double item : maps_A.get(i)){
//						fWriter.write(item+"\t");
//					}
//					fWriter.close();
//				}
//
//				for (int i = 0; i < maps_B.size(); i ++) {
//					fWriter = new FileWriter(path + subject + "\\abnormal\\map_nega\\"+(i+1));
//					for(Double item : maps_B.get(i)){
//						fWriter.write(item+"\t");
//					}
//					fWriter.close();
//				}
			}

		} catch (IOException e1) { // TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	public void OneSidePaaClassifier(String subject,int N_segment) { //自己给段数的PAA特征提取的KNN分类器
		Config config;
		try {
			config = new GetConfig().getConfig();
			logger.info(config);

			String path = config.getPath();

			String filePath = path + subject + "_extract";
			String trainPath = path + subject + "\\train.txt";
			String testPath = path + subject + "\\test.txt";

			ReadData readData = new ReadData();
			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature = new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();


			List<DataItem> data = new ArrayList<DataItem>();
			List<List<Long>> timepoints = new ArrayList<>();
			List<List<Long>> testpoints = new ArrayList<>();
			try {
				data = readData.readPAMAPDataFromFile(filePath, true, dimension);
				timepoints = readData.readTimePoint(trainPath, true);

				testpoints = readData.readTimePoint(testPath, true);
			} catch (Exception e) {
				// TODO Auto-generated catch block e.printStackTrace();
			}
			if (data.size() > 0) {
				long begin = System.currentTimeMillis();
				Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(),
						config.getInterval());

				// two-class
				List<List<DataItem>> data_A = slideWindow.extractWindow(feature.getAbnormal(), timepoints.get(0),
						config.getWindow_length());
				List<List<DataItem>> data_B = slideWindow.extractWindow(feature.getAbnormal(), timepoints.get(1),
						config.getWindow_length());

				List<List<DataItem>> test_A = slideWindow.extractWindow(feature.getAbnormal(), testpoints.get(0),
						config.getWindow_length());
				List<List<DataItem>> test_B = slideWindow.extractWindow(feature.getAbnormal(), testpoints.get(1),
						config.getWindow_length());

				List<List<Double>> maps_A = new ArrayList<>();
				List<List<Double>> maps_B = new ArrayList<>();

				List<List<Double>> testmaps_A = new ArrayList<>();
				List<List<Double>> testmaps_B = new ArrayList<>();

				for (int i = 0; i < data_A.size(); i++) {
					List<Double> map = handelFeature.handlePaaFeature(data_A.get(i), N_segment);
					maps_A.add(map);
				}

				for (int i = 0; i < data_B.size(); i++) {
					List<Double> map = handelFeature.handlePaaFeature(data_B.get(i), N_segment);
					maps_B.add(map);
				}

				for (int i = 0; i < test_A.size(); i++) {
					List<Double> map = handelFeature.handlePaaFeature(test_A.get(i), N_segment);
					testmaps_A.add(map);
				}

				for (int i = 0; i < test_B.size(); i++) {
					List<Double> map = handelFeature.handlePaaFeature(test_B.get(i), N_segment);
					testmaps_B.add(map);
				}

				logger.info("Training Phase(Class A)");
				handleDistance.calAccuracy(maps_A, maps_B, maps_A, config.getK());

				logger.info("Training Phase(Class B)");
				handleDistance.calAccuracy(maps_B, maps_A, maps_B, config.getK());

				logger.info("Class A: ");
				handleDistance.calAccuracy(maps_A, maps_B, testmaps_A, config.getK());

				logger.info("Class B: ");
				handleDistance.calAccuracy(maps_B, maps_A, testmaps_B, config.getK());
				long end = System.currentTimeMillis();
				logger.info("Run for " + (end - begin) / (double) 1000 + "seconds.");

				List<DataItem> data_full =
						readData.readPAMAPDataFromFile(filePath, dimension);
				printOneSidePattern(data_full, data_A, data_B, path +  //
						subject, config.getWindow_length(), 0);
				printOneSidePattern(data_full, test_A, test_B, path +
						subject, config.getWindow_length(), 1);

//				FileWriter fWriter = null;
//
//				for(int i = 0; i < data_A.size(); i ++){
//					fWriter = new FileWriter(path + subject + "\\abnormal\\posi\\"+(i+1));
//					for(DataItem dItem : data_A.get(i)){
//						fWriter.write(dItem.getTimestamp()+"\t"+dItem.getValue()+"\r\n");
//					}
//					fWriter.close();
//				}
//
//				for(int i = 0; i < data_B.size(); i ++){
//					fWriter = new FileWriter(path + subject + "\\abnormal\\nega\\"+(i+1));
//					for(DataItem dItem : data_B.get(i)){
//						fWriter.write(dItem.getTimestamp()+"\t"+dItem.getValue()+"\r\n");
//					}
//					fWriter.close();
//				}
//
//				for (int i = 0; i < maps_A.size(); i ++) {
//					fWriter = new FileWriter(path + subject + "\\abnormal\\map_posi\\"+(i+1));
//					for(Double item : maps_A.get(i)){
//						fWriter.write(item+"\t");
//					}
//					fWriter.close();
//				}
//
//				for (int i = 0; i < maps_B.size(); i ++) {
//					fWriter = new FileWriter(path + subject + "\\abnormal\\map_nega\\"+(i+1));
//					for(Double item : maps_B.get(i)){
//						fWriter.write(item+"\t");
//					}
//					fWriter.close();
//				}
			}

		} catch (IOException e1) { // TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}





	public static void printOneSidePattern(List<DataItem> data, List<List<DataItem>> A, List<List<DataItem>> B,
			String path, long window_length, int flag) throws IOException {
		BinarySearch binarySearch = new BinarySearch();
		WriteData writeData = new WriteData();
		List<List<DataItem>> posi = new ArrayList<>();
		List<List<DataItem>> nega = new ArrayList<>();
		for (List<DataItem> window : A) {

			long mid = 0;
			double max = 0;
			for (DataItem di : window) {
				if (di.getValue() > max) {
					mid = di.getTimestamp();
					max = di.getValue();
				}
			}

			long begin = mid - window_length / 2;
			int begin_index = binarySearch.binarySearch(data, begin, 1);
			long end = mid + window_length / 2;
			int end_index = binarySearch.binarySearch(data, end, 0);

			posi.add(data.subList(begin_index, end_index + 1));

		}

		for (List<DataItem> window : B) {

			long mid = 0;
			double max = 0;
			for (DataItem di : window) {
				if (di.getValue() > max) {
					mid = di.getTimestamp();
					max = di.getValue();
				}
			}

			long begin = mid - window_length / 2;
			int begin_index = binarySearch.binarySearch(data, begin, 1);
			long end = mid + window_length / 2;
			int end_index = binarySearch.binarySearch(data, end, 0);

			nega.add(data.subList(begin_index, end_index + 1));

		}
		if (flag == 0) {
			writeData.writeDataUCRFormat(path + "\\dataset\\traindata", posi, nega, ",");
		} else {
			writeData.writeDataUCRFormat(path + "\\dataset\\testdata", posi, nega,",");
		}

	}

	public void TwoSidesClassifier(String subject) {
		Config config;
		try {
			config = new GetConfig().getConfig();
			logger.info(config);

			String path = config.getPath();

			String filePath = path + subject + "_extract";
			String trainPath = path + subject + "\\train.txt";
			String testPath = path + subject + "\\test.txt";

			ReadData readData = new ReadData();
			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature = new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();

			List<DataItem> data_posi = new ArrayList<DataItem>();
			List<DataItem> data_nega = new ArrayList<DataItem>();
			List<List<Long>> timepoints = new ArrayList<>();
			List<List<Long>> testpoints = new ArrayList<>();
			try {
				data_posi = readData.readPAMAPDataFromFile(filePath, true, dimension);
				data_nega = readData.readPAMAPDataFromFile(filePath, false, dimension);
				timepoints = readData.readTimePoint(trainPath, true);
				testpoints = readData.readTimePoint(testPath, true);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (data_posi.size() > 0 && data_nega.size() > 0) {
				long begin = System.currentTimeMillis();
				Feature feature_posi = extractFeature.getFeature(data_posi, config.getThreshold_window(),
						config.getProbability(), config.getInterval());
				Feature feature_nega = extractFeature.getFeature(data_nega, config.getThreshold_window(),
						config.getProbability(), config.getInterval());

				// two-class
				List<List<List<DataItem>>> data_A = slideWindow.extractWindow(feature_posi.getAbnormal(),
						feature_nega.getAbnormal(), timepoints.get(0), config.getWindow_length());
				List<List<List<DataItem>>> data_B = slideWindow.extractWindow(feature_posi.getAbnormal(),
						feature_nega.getAbnormal(), timepoints.get(1), config.getWindow_length());

				List<List<List<DataItem>>> test_A = slideWindow.extractWindow(feature_posi.getAbnormal(),
						feature_nega.getAbnormal(), testpoints.get(0), config.getWindow_length());
				List<List<List<DataItem>>> test_B = slideWindow.extractWindow(feature_posi.getAbnormal(),
						feature_nega.getAbnormal(), testpoints.get(1), config.getWindow_length());

				List<List<Double>> maps_A = new ArrayList<>();
				List<List<Double>> maps_B = new ArrayList<>();

				List<List<Double>> testmaps_A = new ArrayList<>();
				List<List<Double>> testmaps_B = new ArrayList<>();

				for (int i = 0; i < data_A.size(); i++) {
					List<Double> map = new ArrayList<>();
					for (int j = 0; j < 2; j++) {
						map.addAll(handelFeature.handleFeature(data_A.get(i).get(j), config.getN_segment()));
					}
					maps_A.add(map);

				}

				for (int i = 0; i < data_B.size(); i++) {
					List<Double> map = new ArrayList<>();
					for (int j = 0; j < 2; j++) {
						map.addAll(handelFeature.handleFeature(data_B.get(i).get(j), config.getN_segment()));
					}
					maps_B.add(map);
				}

				for (int i = 0; i < test_A.size(); i++) {
					List<Double> map = new ArrayList<>();
					for (int j = 0; j < 2; j++) {
						map.addAll(handelFeature.handleFeature(test_A.get(i).get(j), config.getN_segment()));
					}
					testmaps_A.add(map);
				}

				for (int i = 0; i < test_B.size(); i++) {
					List<Double> map = new ArrayList<>();
					for (int j = 0; j < 2; j++) {
						map.addAll(handelFeature.handleFeature(test_B.get(i).get(j), config.getN_segment()));
					}
					testmaps_B.add(map);
				}

				logger.info("Training Phase(Class A)");
				handleDistance.calAccuracy(maps_A, maps_B, maps_A, config.getK());

				logger.info("Training Phase(Class B)");
				handleDistance.calAccuracy(maps_B, maps_A, maps_B, config.getK());

				logger.info("Class A: ");
				handleDistance.calAccuracy(maps_A, maps_B, testmaps_A, config.getK());

				logger.info("Class B: ");
				handleDistance.calAccuracy(maps_B, maps_A, testmaps_B, config.getK());
				long end = System.currentTimeMillis();
				logger.info("Run for " + (end - begin) / (double) 1000 + "seconds.");

				List<DataItem> data_full = readData.readPAMAPDataFromFile(filePath, dimension);
				printPattern(data_full, data_A, data_B, path + subject, config.getWindow_length(), 0);
				printPattern(data_full, test_A, test_B, path + subject, config.getWindow_length(), 1);
			}

		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	public static void printPattern(List<DataItem> data, List<List<List<DataItem>>> A, List<List<List<DataItem>>> B,
			String path, long window_length, int flag) throws IOException {
		BinarySearch binarySearch = new BinarySearch();
		WriteData writeData = new WriteData();
		List<List<DataItem>> posi = new ArrayList<>();
		List<List<DataItem>> nega = new ArrayList<>();
		for (List<List<DataItem>> window : A) {

			long mid = 0;
			double max = 0;
			for (DataItem di : window.get(0)) {
				if (di.getValue() > max) {
					mid = di.getTimestamp();
					max = di.getValue();
				}
			}

			long begin = mid - window_length / 2;
			int begin_index = binarySearch.binarySearch(data, begin, 1);
			long end = mid + window_length / 2;
			int end_index = binarySearch.binarySearch(data, end, 0);

			posi.add(data.subList(begin_index, end_index + 1));

		}

		for (List<List<DataItem>> window : B) {

			long mid = 0;
			double max = 0;
			for (DataItem di : window.get(0)) {
				if (di.getValue() > max) {
					mid = di.getTimestamp();
					max = di.getValue();
				}
			}

			long begin = mid - window_length / 2;
			int begin_index = binarySearch.binarySearch(data, begin, 1);
			long end = mid + window_length / 2;
			int end_index = binarySearch.binarySearch(data, end, 0);

			nega.add(data.subList(begin_index, end_index + 1));

		}
		if (flag == 0) {
			writeData.writeDataUCRFormat(path + "\\dataset\\traindata", posi, nega);
		} else {
			writeData.writeDataUCRFormat(path + "\\dataset\\testdata", posi, nega);
		}
	}

	public void TimeRangeClassifier(String subject, Activities lable, PAMAPDimension dimension) {
		Config config;
		try {
			config = new GetConfig().getConfig();
			logger.info(config);

			String path = config.getPath();

			String filePath = path + subject + "_extract";

			ReadData readData = new ReadData();
			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature = new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();

			List<DataItem> data = new ArrayList<DataItem>();
			BeginEndTime bet = new BeginEndTime();
			try {
				data = readData.readPAMAPDataFromFile(filePath, true, dimension);
				bet = readData.readPAMAPTimeFile(filePath, lable);
			} catch (IOException e) {
			}
			if (data.size() > 0 && bet.getBegin() * bet.getEnd() != 0) {
				Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(),
						config.getInterval());
				List<List<DataItem>> datas = slideWindow.extractWindow(feature.getAbnormal(),
						config.getWindow_length());  ///抽取abnormal的窗口
				long mark_time = 0;
				List<List<Double>> maps = new ArrayList<>();
				List<List<Double>> maps_posi = new ArrayList<>();
				for (int i = 0; i < datas.size(); i++) {
					if (datas.get(i).get(0).getTimestamp() > mark_time) {
						mark_time = datas.get(i).get(0).getTimestamp();
						List<Double> map = handelFeature.handleFeature(datas.get(i), config.getN_segment());

						if (mark_time >= bet.getBegin() * 10000 && mark_time < bet.getEnd() * 10000) {   //这里为什么要乘10000
							maps_posi.add(map);
							continue;
						}

						maps.add(map);
					}
				}

				List<List<DataItem>> map_distance = handleDistance.calDistance(maps, maps_posi, 1);
				logger.info("FalsePositve: ");
				handleDistance.analyzeDistance(map_distance, config.getK());

				map_distance = handleDistance.calDistance(maps_posi, maps, 0);
				logger.info("TruePositive: ");
				handleDistance.analyzeDistance(map_distance, config.getK());
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
}
